import cv2
import numpy as np
import pylab

lena_noise = cv2.imread("train_image/book_scale.png", 0)
# 均值滤波
# lena_deal = cv2.blur(lena_noise, (5, 5))
# lena_noise = np.concatenate(
#     (np.expand_dims(lena_noise, axis=2), np.expand_dims(lena_noise, axis=2), np.expand_dims(lena_noise, axis=2)),
#     axis=-1)
# lena_deal = np.concatenate(
#     (np.expand_dims(lena_deal, axis=2), np.expand_dims(lena_deal, axis=2), np.expand_dims(lena_deal, axis=2)),
#     axis=-1)
# pylab.subplot(1, 2, 1)
# pylab.imshow(lena_noise)
# pylab.subplot(1, 2, 2)
# pylab.imshow(lena_deal)
# pylab.show()

# 二、cv2.boxFilter(img,-1,ksize,normalize=True) 方框滤波
# 说明：当normalize=True时，与均值滤波结果相同， normalize=False，表示对加和后的结果不进行平均操作，大于255的使用255表示。
# lena_deal_1=cv2.boxFilter(lena_noise,-1,(5,5))
# lena_deal_2=cv2.boxFilter(lena_noise,-1,(5,5),normalize=False)
# lena_noise = np.concatenate((np.expand_dims(lena_noise, axis = 2), np.expand_dims(lena_noise, axis = 2), np.expand_dims(lena_noise, axis = 2)),
#                          axis = -1)
# lena_deal_1 = np.concatenate((np.expand_dims(lena_deal_1, axis = 2), np.expand_dims(lena_deal_1, axis = 2), np.expand_dims(lena_deal_1,axis = 2)),
#                          axis = -1)
# lena_deal_2= np.concatenate((np.expand_dims(lena_deal_2, axis = 2), np.expand_dims(lena_deal_2, axis = 2), np.expand_dims(lena_deal_2, axis = 2)),
#                          axis = -1)
# pylab.subplot(1,3,1)
# pylab.imshow(lena_noise)
# pylab.subplot(1,3,2)
# pylab.imshow(lena_deal_1)
# pylab.subplot(1,3,3)
# pylab.imshow(lena_deal_2)
# pylab.show()


# lena_deal=cv2.GaussianBlur(lena_noise,(3,3),0,0)
# lena_noise = np.concatenate((np.expand_dims(lena_noise, axis = 2), np.expand_dims(lena_noise, axis = 2), np.expand_dims(lena_noise, axis = 2)),
#                          axis = -1)
# lena_deal = np.concatenate((np.expand_dims(lena_deal, axis = 2), np.expand_dims(lena_deal, axis = 2), np.expand_dims(lena_deal,axis = 2)),
#                          axis = -1)
# pylab.subplot(1,2,1)
# pylab.imshow(lena_noise)
# pylab.subplot(1,2,2)
# pylab.imshow(lena_deal)
# pylab.show()

# 中值滤波
# 原理：中心点的像素被核中中位数的像素值代替。
# 缺点：由于需要对周围的像素值进行排序所以需要的计算量比较大
# lena_deal=cv2.medianBlur(lena_noise,5)
# lena_noise = np.concatenate((np.expand_dims(lena_noise, axis = 2), np.expand_dims(lena_noise, axis = 2), np.expand_dims(lena_noise, axis = 2)),
#                          axis = -1)
# lena_deal = np.concatenate((np.expand_dims(lena_deal, axis = 2), np.expand_dims(lena_deal, axis = 2), np.expand_dims(lena_deal,axis = 2)),
#                          axis = -1)
# pylab.subplot(1,2,1)
# pylab.imshow(lena_noise)
# pylab.subplot(1,2,2)
# pylab.imshow(lena_deal)
# pylab.show()

# 双边滤波是一种非线性的滤波方法，是结合图像的空间邻近度和像素值相似度的一种折衷处理，同时考虑空间与信息和灰度相似性，达到保边去噪的目的。
# 之所以能够达到保边去噪的滤波效果是因为滤波器由两个函数构成：
# 1.一个函数是由几何空间距离决定滤波器系数
# 2.另一个是由像素差值决定滤波器系数。
# 缺点：处理耗时。
# 优点：在滤波的同时能保证一定的边缘信息。
# lena_deal=cv2.bilateralFilter(lena_noise,3,100,100)
# lena_noise = np.concatenate((np.expand_dims(lena_noise, axis = 2), np.expand_dims(lena_noise, axis = 2), np.expand_dims(lena_noise, axis = 2)),
#                          axis = -1)
# lena_deal = np.concatenate((np.expand_dims(lena_deal, axis = 2), np.expand_dims(lena_deal, axis = 2), np.expand_dims(lena_deal,axis = 2)),
#                          axis = -1)
# pylab.subplot(1,2,1)
# pylab.imshow(lena_noise)
# pylab.subplot(1,2,2)
# pylab.imshow(lena_deal)
# pylab.show()

#2D卷积
# 原理：它只取内核区域下所有像素的平均值并替换中心元素。3x3标准化的盒式过滤器如下所示：
kernel = np.ones((5,5),np.float32)/25
lena_deal = cv2.filter2D(lena_noise,-1,kernel)
lena_noise = np.concatenate((np.expand_dims(lena_noise, axis = 2), np.expand_dims(lena_noise, axis = 2), np.expand_dims(lena_noise, axis = 2)),
                         axis = -1)
lena_deal = np.concatenate((np.expand_dims(lena_deal, axis = 2), np.expand_dims(lena_deal, axis = 2), np.expand_dims(lena_deal,axis = 2)),
                         axis = -1)
pylab.subplot(1,2,1)
pylab.imshow(lena_noise)
pylab.subplot(1,2,2)
pylab.imshow(lena_deal)
pylab.show()